package zzh_Jdbc1;

import java.sql.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class TestDriver1 {

    public static void main(String[] args) {
        testJDBC();
    }

    /**
     * java原生连接jdbc
     * 注意:
     * 1、java 的 jdbc连接的工具类都来自于 java.sql包，不要引错包
     * 2、数据库操作过程中的集合，比如resultset的下标是从1开始的
     */

    public static void testJDBC() {
        // 0 准备工作 在项目目录下新建一个lib目录，考入mysql驱动包，设置jar项目引用
        // 1 注册数据驱动
        // 数据库jdbc连接属性信息
        // uri mysql5和mysql8 连接串不一样，8要求有时区属性
        // localhost - 数据库服务器主机名，或者ip地址， 127.0.0.1 表示本机
        // 注意： 如果连接串解析是被，要注意可能是因为 & 引起的，因为有时需要 使用 & 的html转移符号  &amp;

        String strUri5 = "jdbc:mysql://localhost:3306/nuc210531?useUnicode=true&characterEncoding=utf8";
        //String strUri8 = "jdbc:mysql://localhost:3306/nuc210531?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong&allowPublicKeyRetrieval=true";
        // drivername的名字 mysql5和mysql8 不一样
        String strDriverName5 ="com.mysql.jdbc.Driver";
        //String strDriverName8 = "com.mysql.cj.jdbc.Driver";
        String strUserName = "zhaozhihao";
        String strUserPsw = "990928";

        // 注册驱动

//        try {
//            Class.forName(strDriverName5);
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        }
        try {
            //获取数据库连接对象
            Connection connection = DriverManager.getConnection(strUri5,strUserName,strUserPsw);
            //获取查询器
            Statement statement = connection.createStatement();
            //准备sql语句
            String strSql = "SELECT * FROM user";
            //获取查询结果集
            ResultSet resultSet = statement.executeQuery(strSql);
            //遍历结果集，进行业务逻辑处理
            //可以使用迭代方法进行遍历
            if (resultSet != null){
                while (resultSet.next()){
                    //使用getxxx方法获取指定名字或者下标的字段值
                    System.out.println(" 姓名：" + resultSet.getObject("userName") +
                            "; 学号：" + resultSet.getObject(2));
                }
            }
            // TODO 查询完之后，需要将ResultSet中的结果数据，转储到一个集合数据结构中【List+Map】
            //  然后关闭数据库资源，进行资源回收，减轻数据库服务器的压力； 写一个公用的方法完成这个业务处理；
            /*
              思路提示：
                 在resultset结果集中通过 ResultSetMetaData getMetaData()  方法可以获取，查询结果集中于列信息相关的数据，可以获取 列数；
                 可通过列数的下表获取列表，然可以通过列名从 resultset结果集中获取对应列的值，然后，以列名为key ，以列值为value，存入 map中；
                 然后map存入 list中，这样就完成了查询结果集 resultset的转储业务处理；
             */

            // 业务需要再一次遍历查询结果集的数据
            // 可以使用迭代的方式进行遍历
            // 因为resulstset结果集中使用的是 游标 进行查询结果的遍历 游标只能从前往后移动，到末尾结束
            // 如果再次遍历的话，需要将游标重置到开始位置
            // 回收资源
            resultSet.beforeFirst();
            System.out.println("再次遍历查询结果集中的数据：");
            System.out.println("将数据库中的数据转储到List+Map的结果集：");
            List<Map<String,Object>> listResultSet = new ArrayList<>();

            if (resultSet != null) {
                //获取查询当前结果集列信息
                ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
                //获取当前结果集中的列数
                int columnCount = resultSetMetaData.getColumnCount();
                while (resultSet.next()) {
                    //保存当前行数据的Map对象，因为需要有序，所以使用MLInkedHashMap
                    Map<String,Object> map = new LinkedHashMap<>();
                    // 通过列数for循环获取每一列的名字，通过获取的列明，获取对应的列值
                    for (int i =1;i <= columnCount;i++){
                        // 获取对应下标的列名
                        String strColumnName = resultSetMetaData.getColumnName(i);
                        //通过列名获取对相应的列值
                        Object objColumnValue = resultSet.getObject(strColumnName);
                        //把列名-列值 键值对存入map中
                        map.put(strColumnName,objColumnValue);
                    }
                    // 把保存每一行数据的map存入list中，一个map表示一行数据
                    listResultSet.add(map);
                    //使用getxxx方法获取指定名字或者下标的字段值
                    System.out.println(" 姓名：" + resultSet.getObject("userName") +
                            "; 性别：" + resultSet.getObject(3));
                }
            }
            // 测试转储结果
            System.out.println("转储结果：");
            System.out.println(listResultSet);


            // 如果再次遍历的话，需要将游标重置到开始位置
            resultSet.beforeFirst();
            System.out.println("关闭查询器之后，再次遍历查询结果集中的数据：");
            if (resultSet != null) {
                while (resultSet.next()) {
                    //使用getxxx方法获取指定名字或者下标的字段值
                    System.out.println(" 姓名：" + resultSet.getObject("userName") +
                            "; 学号：" + resultSet.getObject(2));
                }
            }
            resultSet.close();
            statement.close();
            connection.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            // 也可以在这里回收资源
        }

    }

}
